<template>
  <div class="stepper">
    <button
      class="pp-button stepper__action "
      :class="{ 'stepper__action--disabled': disabled || minusDisabled }"
      hover-class="pp-button--active"
      @click="handleClick('minus')"
      @touchstart="handletouchStart('minus')"
      @touchend="handletouchEnd()"
    >
      <span class="stepper__action--minus"></span>
    </button>
    <input
      type="number"
      class="stepper__input"
      maxlength="4"
      :value="value"
      :disabled="disabled || disableInput"
      @input="handleChange"
    />
    <button
      class="pp-button stepper__action"
      :class="{ 'stepper__action--disabled': disabled || plusDisabled }"
      hover-class="pp-button--active"
      @click="handleClick('plus')"
      @touchstart="handletouchStart('plus')"
      @touchend="handletouchEnd()"
    >
      <span class="stepper__action--plus"></span>
    </button>
  </div>
</template>

<script>
import { add, LONG_PRESS_START_TIME, LONG_PRESS_INTERVAL } from './utils';

let LongPressTimer;
export default {
  name: 'Stepper',
  props: {
    count: {
      type: [Number, String],
      default: 1,
    },
    min: {
      type: [Number, String],
      default: 1,
    },
    max: {
      type: [Number, String],
      default: 99,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    disableInput: {
      type: Boolean,
      default: false,
    },
    longPress: {
      type: Boolean,
      default: true,
    },
  },
  watch: {
    count(val) {
      this.value = val;
    },
    max(val) {
      if(this.value > val) {
        this.value = 1;
      }
    },
    value(val) {
      if(val) {
        this.$emit('onchange', val);
      }
    }
  },
  data() {
    const value = this.count || 1;
    return {
      value,
    };
  },
  computed: {
    minusDisabled() {
      return this.value <= this.min;
    },
    plusDisabled() {
      return this.value >= this.max;
    },
  },
  methods: {
    handleChange(e) {
      let count = +e.detail.value;
      if(count < this.min) {
        count = this.min;
      }else if(count > this.max) {
        count = this.max;
      }
      // 处理连续输入边界外的数据时不更新UI
      this.value = '';
      this.$nextTick(() => {
        this.value = count;
      });
    },
    handleClick(type) {
      if (this.isDisabled(type)) {
        return;
      }
      const count = add(+this.value, type === 'plus' ? 1 : -1);
      this.value = count;
    },
    handletouchStart(type) {
      if (!this.longPress) {
        return;
      }
      clearTimeout(LongPressTimer);
      LongPressTimer = setTimeout(() => {
        this.handleClick(type);
        this.longPressStep(type);
      }, LONG_PRESS_START_TIME);
    },
    handletouchEnd() {
      if (!this.longPress) {
        return;
      }
      clearTimeout(LongPressTimer);
    },
    longPressStep(type) {
      LongPressTimer = setTimeout(() => {
        this.handleClick(type);
        this.longPressStep(type);
      }, LONG_PRESS_INTERVAL);
    },
    isDisabled(type) {
      if (type === 'plus') {
        return this.disabled || this.value >= this.max;
      }
      return this.disabled || this.value <= this.min;
    },
  },
};
</script>

<style scoped lang="less">
.stepper {
  display: flex;
  align-items: center;
  &__action {
    width: 60rpx;
    height: 60rpx;
    border-radius: 100%;
    box-sizing: border-box;
    background: #f2f3f5;
    color: #333;
    position: relative;
    &--minus::before,
    &--plus::before {
      content: ' ';
      width: 26rpx;
      height: 4rpx;
      background: #333;
      border-radius: 4rpx;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    &--plus {
      &::after {
        content: ' ';
        width: 4rpx;
        height: 26rpx;
        background: #333;
        border-radius: 4rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    }
    &--disabled {
      background: #f8f8f8;
      .stepper__action--minus,
      .stepper__action--plus {
        &::before {
          background: #ccc;
        }
      }
      .stepper__action--plus {
        &::after {
          background: #ccc;
        }
      }
      &.pp-button--active {
        &::before {
          opacity: 0;
        }
      }
    }
  }
  &__input {
    width: 64rpx;
    height: 60rpx;
    box-sizing: border-box;
    min-height: 0;
    text-align: center;
    border: none;
    border-radius: 0;
    -webkit-appearance: none;
    font-size: 28rpx;
    color: #333;
    margin: 0 4rpx;
  }
}
</style>
